package com.project.blog.controller;

import com.project.blog.common.result.Result;
import com.project.blog.common.result.ResultCode;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@RestController
public class UploadController {


    private static final Logger logger = LoggerFactory.getLogger(UploadController.class);


    @Value("${me.upload.path}")
    private String baseFolderPath;

    @PostMapping("/upload")
    @RequiresAuthentication
   // @LogAnnotation(module = "文件上传", operation = "文件上传")
    public Result upload(HttpServletRequest request, MultipartFile image) {

        Result r = new Result();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

        StringBuffer url = new StringBuffer();
        String filePath = sdf.format(new Date());

        File baseFolder = new File(baseFolderPath + filePath);
        if (!baseFolder.exists()) {
            baseFolder.mkdirs();
        }

        final String scheme = request.getScheme();
        final String serverName = request.getServerName();
        final int serverPort = request.getServerPort();
        final String contextPath = request.getContextPath();
        url.append(scheme)
                .append("://")
                .append(serverName)
                .append(":")
                .append(serverPort)
                .append(contextPath)
                .append("/")
                .append(filePath);

        String imgName = UUID.randomUUID() + "_" + image.getOriginalFilename().replaceAll(" ", "");

        try {

            File dest = new File(baseFolder, imgName);
            image.transferTo(dest);

            url.append("/").append(imgName);

            r.setResultCode(ResultCode.SUCCESS);

            r.simple().put("url", url);

        } catch (IOException e) {
            logger.error("文件上传错误 , uri: {} , caused by: ", request.getRequestURI(), e);
            r.setResultCode(ResultCode.UPLOAD_ERROR);
        }

        return r;
    }




    @GetMapping("/{date}/{fileName}.{suff}")
    public void download(
                         @PathVariable("date") String date,
                         @PathVariable("fileName") String fileName,
                         @PathVariable("suff") String suff,
                         HttpServletResponse httpServletResponse) {
        String path = baseFolderPath+ date.concat("/")+fileName.concat(".")+suff;
        File file = new File(path);
        down(httpServletResponse, file, fileName);
    }

    private void down(HttpServletResponse httpServletResponse, File file, String newFileName) {
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        try {
            byte[] buffer = new byte[1024];
            httpServletResponse.setContentType("application/force-download");
            httpServletResponse.setCharacterEncoding("utf-8");
            // 设置下载不打开、文件名、和编码，不然打不出名称
            // httpServletResponse.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(newFileName, "utf-8"));
            httpServletResponse.addHeader("content-type", "attachment;fileName=" + URLEncoder.encode(newFileName, "utf-8"));
            fis = new FileInputStream(file);
            bis = new BufferedInputStream(fis);
            OutputStream os = httpServletResponse.getOutputStream();
            int i = bis.read(buffer);
            while (i != -1) {
                os.write(buffer, 0, i);
                i = bis.read(buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
